package com.jxl.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.gson.Gson;
import com.jxl.common.auth.Roles;
import com.jxl.common.enums.DeletedCodeEnum;
import com.jxl.common.redis.RedisUtil;
import com.jxl.domain.convert.AuthUserBOConvert;
import com.jxl.domain.entity.AuthUserBO;
import com.jxl.domain.entity.AuthUserRoleBO;
import com.jxl.domain.service.AuthRolePermessionDomainService;
import com.jxl.domain.service.AuthUserDomainService;
import com.jxl.domain.service.AuthUserRoleDomainService;
import com.jxl.infra.basic.entity.*;
import com.jxl.infra.basic.service.AuthPermissionService;
import com.jxl.infra.basic.service.AuthRolePermissionService;
import com.jxl.infra.basic.service.AuthRoleService;
import com.jxl.infra.basic.service.AuthUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

    @Resource
    private AuthUserService authUserService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private AuthUserRoleDomainService authUserRoleDomainService;

    @Resource
    private AuthRolePermissionService  authRolePermissionService;

    @Resource
    private AuthPermissionService authPermissionService;

    @Resource
    private AuthRoleService authRoleService;

    private final String salt = "qawosnd";

    private String authPermissionPrefix = "auth.permission";

    private String authRolePrefix = "auth.role";

    private static final String LOGIN_PREFIX = "loginCode";


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean register(AuthUserBO authUserBO) {
        AuthUser authUser =
                AuthUserBOConvert.INSTANCE.convertBOToAuthUser(authUserBO);
        //密码加盐
        authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(),salt));
        //设置默认头像
        authUser.setAvatar("http://192.168.152.134:9000/jc-club/头像/默认.jpg");
        Integer insert = authUserService.insert(authUser);
        //默认分配角色
        AuthRole authRole = new AuthRole();
        authRole.setRoleKey(Roles.NORMAL_USER);
        AuthRole newRoles = authRoleService.queryByCondition(authRole);
        //插入数据
        AuthUserRoleBO authUserRoleBO = new AuthUserRoleBO();
        authUserRoleBO.setUserId(authUser.getId());
        authUserRoleBO.setRoleId(newRoles.getId());
        authUserRoleDomainService.add(authUserRoleBO);

        //根据默认分配的角色，插入到redis里面
        String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        List<AuthRole> roleList = new LinkedList<>();
        roleList.add(newRoles);
        redisUtil.set(roleKey,new Gson().toJson(roleList));

        //根据角色查询出权限
        AuthRolePermission authRolePermission = new AuthRolePermission();
        authRolePermission.setRoleId(newRoles.getId());
        List<AuthRolePermission> rolePermissionList = authRolePermissionService.
                queryByCondition(authRolePermission);
        //获取出权限id集合
        List<Long> permessionIdList = rolePermissionList.stream().
                map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
        //查询出权限
        List<AuthPermission> permissionList = authPermissionService.queryByRoleList(permessionIdList);

        //再将该用户的权限进行redis储存  h
        String permessionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
        redisUtil.set(permessionKey,new Gson().toJson(permissionList));
        return insert>0;
    }

    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser =
                AuthUserBOConvert.INSTANCE.convertBOToAuthUser(authUserBO);
        Integer update = authUserService.update(authUser);
        return update>0;
    }

    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser =
                AuthUserBOConvert.INSTANCE.convertBOToAuthUser(authUserBO);
        authUser.setIsDeleted(DeletedCodeEnum.DELETE.getCode());
        Integer update = authUserService.update(authUser);
        return update>0;
    }

    @Override
    public Boolean updateStatus(AuthUserBO authUserBO) {
        AuthUser authUser =
                AuthUserBOConvert.INSTANCE.convertBOToAuthUser(authUserBO);
        authUser.setIsDeleted(DeletedCodeEnum.DELETE.getCode());
        Integer update = authUserService.update(authUser);
        return update>0;
    }

    @Override
    public SaTokenInfo doLogin(String code) {
        //验证码校验
        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, code);
        String openId = redisUtil.get(loginKey);
        if (StringUtils.isBlank(openId)) {
            return null;
        }
        //查询是否存在此openid
        AuthUserBO authUser = new AuthUserBO();
        authUser.setUserName(openId);
        authUser.setIsDeleted(DeletedCodeEnum.UN_DELETE.getCode());
        AuthUser authUser1 = AuthUserBOConvert.INSTANCE.convertBOToAuthUser(authUser);
        List<AuthUser> authUsers = authUserService.queryByCondition(authUser1);
        //如果没有注册
        if (authUsers.size()==0){
            this.register(authUser);
        }
        StpUtil.login(openId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return tokenInfo;
    }

    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser = new AuthUser();
        authUser.setUserName(authUserBO.getUserName());
        List<AuthUser> userList = authUserService.queryByCondition(authUser);
        if (CollectionUtils.isEmpty(userList)) {
            return new AuthUserBO();
        }
        AuthUser user = userList.get(0);
        return AuthUserBOConvert.INSTANCE.convertToAuthUserBO(user);
    }

}
